package com.whut.customer.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.whut.common.util.R;
import com.whut.customer.base.BaseController;
import com.whut.customer.bean.CacheUser;
import com.whut.customer.entity.SysUser;
import com.whut.customer.redis.RedisService;
import com.whut.customer.redis.UserKeyTemp;
import com.whut.customer.service.ISysUserService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 系统用户 前端控制器
 * </p>
 *
 * @author author
 * @since 2021-01-22
 */
@RestController
@RequestMapping("/sysUser")
@Slf4j
public class SysUserController extends BaseController {

    @Autowired
    ISysUserService userService;

    @Autowired
    RedisService redisService;

    /**
     * 添加用户,密码使用md5加密
     */
    @ApiOperation("添加用户")
    @PostMapping("/addUser")
//    @RequiresPermissions("user:insert_user")
    public R addUser(@RequestBody SysUser user){
        LambdaQueryWrapper<SysUser> eq = new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, user.getUsername());
        if (userService.getOne(eq) != null)
            return R.failed("该账号已注册!");
        user.setCreateDate(LocalDateTime.now());
        user.setUpdateDate(LocalDateTime.now());
        Long userId = super.userInfo().getId();
        user.setCreator(userId);
        user.setUpdater(userId);
        return R.ok(userService.addUser(user));
    }

    @ApiOperation("用户查询")
    @PostMapping("/selectUser")
//    @RequiresPermissions("user:select_users")
    public R<List<SysUser>> selectUser(@RequestBody SysUser user){
        return R.ok(userService.selectUser(user));
    }

    /**
     * 编辑用户
     */
    @ApiOperation("编辑用户")
    @PostMapping("/updateUser")
//    @RequiresPermissions("user:update")
    public R updateUser(@RequestBody SysUser user){
        if (user.getId() == null) {
            return R.failed("id不能为空!");
        }
        SysUser sysUser = userService.getById(user.getId());
        if (sysUser == null) {
            return R.failed("该用户不存在!");
        }
        user.setUpdateDate(LocalDateTime.now());
        Long currentUserId=super.userInfo().getId();
        user.setUpdater(currentUserId);
        return R.ok(userService.updateUser(user));
    }

    @ApiOperation("查询单个用户")
    @PostMapping("/selectUserById")
//    @RequiresPermissions("user:selectUser")
    public R<SysUser> selectUserById(@PathVariable Long id){
        return R.ok(userService.getById(id));
    }

    @ApiOperation("删除用户")
    @PostMapping("/deleteUser/{id}")
//    @RequiresPermissions("user:delete")
    public R deleteUserInfo(@PathVariable("id") Long id){
        return R.ok(userService.removeById(id));
    }

    @ApiOperation("登录")
    @PostMapping("/login")
    public R<CacheUser> login(@RequestBody SysUser user){
        log.warn("进入登录//////");
        // 将用户名和密码疯转到UsernamePasswordToken中
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        System.out.println(token);
        // 获取Subject实例对象
        Subject subject = SecurityUtils.getSubject();
        CacheUser cacheUser;

        // 认证
        try{
            // 传到ShiroRealm类中的方法进行认证
            subject.login(token);
            // 构建缓存用户信息返回给前端
            SysUser userShiro = (SysUser)subject.getPrincipals().getPrimaryPrincipal();
            cacheUser=CacheUser.builder()
                    .token(subject.getSession().getId().toString())
                    .build();
//            cacheUser.setToken(token.);
            log.warn("token:" + subject.getSession().getId().toString());
            BeanUtils.copyProperties(userShiro,cacheUser);
            log.warn("CacheUser is {}",cacheUser.toString());
        }
        catch(UnknownAccountException e){
            log.error("账户不存在异常：", e);
            return R.failed("用户不存在!");
        }
        catch (IncorrectCredentialsException e){
            log.error("凭据错误（密码错误）异常：", e);
            return R.failed("密码错误!");
        }
        catch (AuthenticationException e){
            log.error("身份验证异常:", e);
            return R.failed("用户校验失败!");
        }

        return R.ok(cacheUser);
    }

    @ApiOperation("退出登录")
    @GetMapping(value="/logout")
    public R logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return R.ok("已退出当前账号");
    }

    @ApiOperation("redis-get测试")
    @RequestMapping("/redis/get")
    public R<SysUser> redisGet(){
        SysUser user=redisService.get(UserKeyTemp.getById,""+1,SysUser.class);
        return R.ok(user);
    }

    @ApiOperation("redis-set测试")
    @RequestMapping("/redis/set")
    public R<Boolean> redisSet(){
        SysUser user  = new SysUser();
        user.setId(2222222L);
//        user.setName("2222");
        redisService.set(UserKeyTemp.getById, ""+2, user);//UserKey:id1
        return R.ok(true);

    }

}
